using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace ErlyThreadsWinFormsDemo
{
	public partial class frmFibonacciDemo : Form
	{
		public frmFibonacciDemo()
		{
			InitializeComponent();

			// create a new runtime with a guid for an ID
			mErlyThreadsRuntime = new ErlyThreads.ProcessRuntime(Guid.NewGuid().ToString());
		}

		readonly ErlyThreads.ProcessRuntime mErlyThreadsRuntime = null;
		readonly string mFibonacciNumberProcessId = Guid.NewGuid().ToString();

		private void Form1_Load(object sender, EventArgs e)
		{
			// create the process that will calculate fibonacci numbers
			mErlyThreadsRuntime.ProcessHandle.InitProcess(
				mFibonacciNumberProcessId,
				FibonacciProcess.FibonacciThreadCode);

			// start the process that will calculate fibonacci numbers
			mErlyThreadsRuntime.ProcessHandle.StartProcess(mFibonacciNumberProcessId);
		}

		private void mBtnCalculate_Click(object sender, EventArgs e)
		{
			// send the message to the fibonacci thread to calculate the nth fibonacci number
			mErlyThreadsRuntime.ProcessHandle.SendMessage(
				mFibonacciNumberProcessId,
				new FibonacciProcess.PleaseCalculateNthFibonacciNumberMessage(Convert.ToInt32(mN.Value)));

			// start the timer that will check for results
			mResultTimer.Enabled = true;
		}

		private void mResultTimer_Tick(object sender, EventArgs e)
		{
			// if no messages arrived yet, quit
			if (mErlyThreadsRuntime.ProcessHandle.NumberOfQueuedMessages == 0) { return; }

			// we are only expecting one type of message in this application
			mErlyThreadsRuntime.ProcessHandle.DispatchQueuedMessages(delegate(ErlyThreads.ReceivedMessage resultMessage)
			{
				FibonacciProcess.NthFibonacciNumberMessage answer = resultMessage.Message as FibonacciProcess.NthFibonacciNumberMessage;
				if (answer == null) { return; }

				// disable the timer since we got the result
				mResultTimer.Enabled = false;

				// we can manipulate the controls directly from here, since we are (of course) still on the same thread
				mLabelAnswer.Text = answer.Answer.ToString();
			});
		}

		private void mBtnQuit_Click(object sender, EventArgs e)
		{
			// we have to stop the fibonaccy thread otherwise the app won't quit
			mErlyThreadsRuntime.ProcessHandle.SendMessage(
				mFibonacciNumberProcessId,
				new FibonacciProcess.PleaseQuitMessage());

			this.Close();
		}

	}
}